﻿package com.reyco1.util
{	
	/*
	class
	*/
	
	/**
	 * Based on the Yahoo Astra base clases.
	 */
	public class DateUtil
	{
		/*
		variables
		*/
		public static var months:Array = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		public static const DAYS_IN_JANUARY:int = 31
		public static const DAYS_IN_FEBRUARY:int = 28;
		public static const DAYS_IN_FEBRUARY_LEAP_YEAR:int = 29;
		public static const DAYS_IN_MARCH:int = 31;
		public static const DAYS_IN_APRIL:int = 30;
		public static const DAYS_IN_MAY:int = 31;
		public static const DAYS_IN_JUNE:int = 30;
		public static const DAYS_IN_JULY:int = 31;
		public static const DAYS_IN_AUGUST:int = 31;
		public static const DAYS_IN_SEPTEMBER:int = 30;
		public static const DAYS_IN_OCTOBER:int = 31;
		public static const DAYS_IN_NOVEMBER:int = 30;
		public static const DAYS_IN_DECEMBER:int = 31;
		public static const DAYS_IN_YEAR:int = 365;
		public static const DAYS_IN_LEAP_YEAR:int = 366;
		public static var daysInMonths:Array = [DAYS_IN_JANUARY, DAYS_IN_FEBRUARY, DAYS_IN_MARCH, DAYS_IN_APRIL, DAYS_IN_MAY, DAYS_IN_JUNE, 
												DAYS_IN_JULY, DAYS_IN_AUGUST, DAYS_IN_SEPTEMBER, DAYS_IN_OCTOBER, DAYS_IN_NOVEMBER, DAYS_IN_DECEMBER];
		
		/**
		 * Determines the number of days between the start value and the end value. The result
		 * may contain a fractional part, so cast it to int if a whole number is desired.
		 * 
		 * @param		start	the starting date of the range
		 * @param		end		the ending date of the range
		 * @return		the number of dats between start and end
		 */
		public static function countDays(start:Date, end:Date):Number
		{
			return Math.abs(end.valueOf() - start.valueOf()) / (1000 * 60 * 60 * 24);
		}
		
		/**
		 * Determines if the input year is a leap year (with 366 days, rather than 365).
		 * 
		 * @param		year	the year value as stored in a Date object.
		 * @return		true if the year input is a leap year
		 */
		public static function isLeapYear(year:int):Boolean
		{
			if(year % 100 == 0){
				return year % 400 == 0;
			}
			return year % 4 == 0;
		}
		
		/**
		 * Gets the name of the month specified by index. This is the month value
		 * as stored in a Date object.
		 * 
		 * @param		index	the numeric value of the month
		 * @return		the string name of the month in English
		 */
		public static function getMonthName(index:int):String
		{
			return months[index];
		}
		
		/**
		 * Gets the abbreviated month name specified by index. This is the month value
		 * as stored in a Date object.
		 * 
		 * @param		index	the numeric value of the month
		 * @return		the short string name of the month in English
		 */
		public static function getShortMonthName(index:int):String
		{
			return getMonthName(index).substr(0, 3);
		}
		
		/**
		 * Rounds a date UP to the nearest time unit
		 * 
		 * @param		dateToRound:	date to round
		 * @param		timeUnit:		the time unit to round up to
		 * @return		the the date object rounded up to
		 */
		public static function roundUp(dateToRound:Date, timeUnit:String = "day"):Date
		{
			dateToRound = new Date(dateToRound.valueOf());
			switch(timeUnit)
			{
				case "year":
					dateToRound.year++;
					dateToRound.month = 0;
					dateToRound.date = 1;
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "month":
					dateToRound.month++;
					dateToRound.date = 1;
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "day":
					dateToRound.date++;
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "hours":
					dateToRound.hours++;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "minutes":
					dateToRound.minutes++;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "seconds":
					dateToRound.seconds++;
					dateToRound.milliseconds = 0;
					break;
				case "milliseconds":
					dateToRound.milliseconds++;
					break;
			}
			return dateToRound;
		}
		/**
		 * Rounds a date DOWN to the nearest time unit
		 * 
		 * @param		dateToRound:	date to round
		 * @param		timeUnit:		the time unit to round down to
		 * @return		the the date object rounded up to
		 */
		public static function roundDown(dateToRound:Date, timeUnit:String = "day"):Date
		{
			dateToRound = new Date(dateToRound.valueOf());
			switch(timeUnit)
			{
				case "year":
					dateToRound.month = 0;
					dateToRound.date = 1;
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "month":
					dateToRound.date = 1;
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "day":
					dateToRound.hours = 0;
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "hours":
					dateToRound.minutes = 0;
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "minutes":
					dateToRound.seconds = 0;
					dateToRound.milliseconds = 0;
					break;
				case "seconds":
					dateToRound.milliseconds = 0;
					break;
			}
			return dateToRound;
		}
		
		public static function secToFormattedTime($seconds:Number):String
		{
			var input:Number = $seconds;
			var time:String = (input > 3600 ? Math.floor(input / 3600) + ":" : "") + (input % 3600 < 600 ? "0" : "") + Math.floor(input%3600/60) + ":" + (input%60 < 10 ? "0":"") + input % 60;
			return time;
		}
	}
}
